﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using TopVisionVideoStream;
using VideoStream.Common;
using VideoStream.Model;

namespace VideoStream.Windows
{
    public partial class Windows_VideoCall : VideoStream.Windows.WindowsBase
    {

        #region Filds

        private BindingSource camSource;
        private BindingSource micSource;
        private BindingSource rslSource;
        private BindingSource spkSource;
        private Windows_Display winDisplay;
        private bool calling = false;

        #endregion


        #region Property

        //private bool VideoCallActive
        //{
        //    get { }
        //    set { }
        //}

        #endregion



        public Windows_VideoCall()
        {
            InitializeComponent();
            InitUI();
            this.Tag = "winVideoCall";
        }

        #region Override Method

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            InitEvent();
            UpdateUI();
        }

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);
            Windows_Main.Instance.ShowMask(false);
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            TVVS.VideoCallResult -= TVVS_VideoCallResult;
        }

        public override void InitUI()
        {
            base.InitUI();

            this.TopLevel = false;
            this.Dock = DockStyle.Fill;
            this.camSource = new BindingSource();
            this.micSource = new BindingSource();
            this.rslSource = new BindingSource();
            this.spkSource = new BindingSource();

            cbox_Camera.DataSource = camSource;
            cbox_Microphone.DataSource = micSource;
            cbox_Resolution.DataSource = rslSource;
            cbox_Speaker.DataSource = spkSource;
        }

        public override void InitEvent()
        {
            base.InitEvent();

            txt_VideoCallInput.TextChanged += Txt_VideoCallInput_TextChanged;
            btn_VideoCall.Click += Btn_VideoCall_Click;
            btn_Hangup.Click += Btn_Hangup_Click;
            TVVS.VideoCallResult += TVVS_VideoCallResult;
            txt_VideoCallInput.KeyPress += Txt_VideoCallInput_KeyPress;

            // captures
            cb_Camera.CheckedChanged += Cb_Camera_CheckedChanged;
            cb_ShardScreen.CheckedChanged += Cb_ShardScreen_CheckedChanged;

            // captures combox
            cbox_Camera.SelectedIndexChanged += CaptureCombox_SelectedIndexChanged;
            cbox_Resolution.SelectedIndexChanged += CaptureCombox_SelectedIndexChanged;
            cbox_Microphone.SelectedIndexChanged += CaptureCombox_SelectedIndexChanged;
            cbox_Speaker.SelectedIndexChanged += CaptureCombox_SelectedIndexChanged;

        }

        public override void UpdateUI()
        {
            base.UpdateUI();

            icon_VideoCall._Text = TVString.STR_NoCalling;
            txt_VideoCallInput.Text = "";
            btn_VideoCall._Text = TVString.STR_Call;

            // Captures List
            UpdateCapturesList();

            InputCheck();

            // Hangup
            btn_Hangup.Visible = false;
            btn_Hangup._Text = TVString.STR_Hangup;

#if DEBUG
            txt_VideoCallInput.Text = "3186019";
#endif

            // Reset tmpdata
            if (!string.IsNullOrEmpty(ApplicationData.tmpCamera))
            {
                cbox_Camera.SelectedItem = ApplicationData.tmpCamera;
            }
            else
            {
                CaptureCombox_SelectedIndexChanged(cbox_Camera, null);
            }

            if (!string.IsNullOrEmpty(ApplicationData.tmpMicrophone))
            {
                cbox_Microphone.SelectedItem = ApplicationData.tmpMicrophone;
            }
            else
            {
                CaptureCombox_SelectedIndexChanged(cbox_Microphone, null);
            }

            if (!string.IsNullOrEmpty(ApplicationData.tmpResolution))
            {
                cbox_Resolution.SelectedItem = ApplicationData.tmpResolution;
            }
            else
            {
                CaptureCombox_SelectedIndexChanged(cbox_Resolution, null);
            }

            if (!string.IsNullOrEmpty(ApplicationData.tmpSpeaker))
            {
                cbox_Speaker.SelectedItem = ApplicationData.tmpSpeaker;
            }

            if (!string.IsNullOrEmpty(ApplicationData.tmpCallID))
            {
                txt_VideoCallInput.Text = ApplicationData.tmpCallID;
            }

            if (!string.IsNullOrEmpty(ApplicationData.tmpCameraSelected))
            {
                cb_Camera.Checked = ApplicationData.tmpCameraSelected == "1";
            }

            if (!string.IsNullOrEmpty(ApplicationData.tmpShardScreen))
            {
                cb_ShardScreen.Checked = ApplicationData.tmpShardScreen == "1";
            }

            Cb_Camera_CheckedChanged(cbox_Camera, null);

            cb_Camera.Text = TVString.STR_Camera;
            lab_Resolution.Text = TVString.STR_Resolution;
            lab_Microphone.Text = TVString.STR_Microphone;
            lab_Speaker.Text = TVString.STR_Speaker;

        }

        #endregion


        #region Control Event

        private void Txt_VideoCallInput_TextChanged(object sender, EventArgs e)
        {
            InputCheck();
        }

        private void Cb_Camera_CheckedChanged(object sender, EventArgs e)
        {
            ApplicationData.tmpCameraSelected = cb_Camera.Checked ? "1" : "0";
            cbox_Camera.Enabled = cb_Camera.Checked;
            if (cb_Camera.Checked)
            {
                cb_ShardScreen.Checked = false;
                cbox_Resolution.Enabled = true;
                CaptureCombox_SelectedIndexChanged(cbox_Camera, null);
            }
            else
            {
                cbox_Resolution.Enabled = cb_ShardScreen.Checked;
                ApplicationData.tmpCameraIndex = -1;
            }
        }

        private void Txt_VideoCallInput_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                VideoCall();
                e.Handled = true;
            }
        }

        private void Cb_ShardScreen_CheckedChanged(object sender, EventArgs e)
        {
            ApplicationData.tmpShardScreen = cb_ShardScreen.Checked ? "1" : "0";
            if (cb_ShardScreen.Checked)
            {
                cb_Camera.Checked = false;
                cbox_Resolution.Enabled = true;
                ApplicationData.tmpCameraIndex = -2;
            }
            else
            {
                cbox_Resolution.Enabled = cb_Camera.Checked;
                Cb_Camera_CheckedChanged(cbox_Camera, null);
            }
        }
        private void Btn_VideoCall_Click(object sender, EventArgs e)
        {
            VideoCall();
        }

        private void Btn_Hangup_Click(object sender, EventArgs e)
        {
            Hangup();
        }

        private void CaptureCombox_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox cb = sender as ComboBox;
            if (cb != null)
            {
                if (cb == cbox_Camera)
                {
                    ApplicationData.tmpCameraIndex = cbox_Camera.SelectedIndex;
                    ApplicationData.tmpCamera = cbox_Camera.SelectedItem == null ? "" : cbox_Camera.SelectedItem.ToString();
                }
                if (cb == cbox_Resolution)
                    ApplicationData.tmpResolution = cbox_Resolution.SelectedItem == null ? "" : cbox_Resolution.SelectedItem.ToString();
                if (cb == cbox_Microphone)
                {
                    ApplicationData.tmpMicrophone = cbox_Microphone.SelectedItem == null ? "" : cbox_Microphone.SelectedItem.ToString();
                    ApplicationData.tmpMicrophoneIndex = cbox_Microphone.SelectedIndex;
                }
                if (cb == cbox_Speaker)
                {
                    ApplicationData.tmpSpeaker = cbox_Speaker.SelectedItem == null ? "" : cbox_Speaker.SelectedItem.ToString();
                    ApplicationData.tmpSpeakerIndex = cbox_Speaker.SelectedIndex;
                }
            }
        }

        #endregion


        #region TVVS Event

        private void TVVS_VideoCallResult(CallStatusType e)
        {
            switch (e)
            {
                case CallStatusType.Failed:
                    CallFiled();
                    ShowCallState(string.Format(TVString.STR_F_CallingFaild, TVVS.CallindID));
                    break;
                case CallStatusType.Checking:
                    break;
                case CallStatusType.None:
                    CallFiled();
                    ShowCallState(string.Format(TVString.STR_F_InvalidCall, TVVS.CallindID));
                    break;
                case CallStatusType.Offline:
                    ShowCallState(string.Format(TVString.STR_F_Offline, TVVS.CallindID));
                    CallFiled();
                    break;
                case CallStatusType.Online:
                    break;
                case CallStatusType.Calling:
                    ShowCallState(string.Format(TVString.STR_F_Connecting, TVVS.CallindID));
                    break;
                case CallStatusType.Connected:
                    ShowCallState(string.Format(TVString.STR_F_Connecting, TVVS.CallindID));
                    Connected();
                    break;
                case CallStatusType.Busy:
                    ShowCallState(string.Format(TVString.STR_F_Busy, TVVS.CallindID));
                    CallFiled();
                    break;
                case CallStatusType.DisConnect:
                    CallFiled();
                    break;
                case CallStatusType.NoAnswer:
                    ShowCallState(string.Format(TVString.STR_F_NoAnswer, TVVS.CallindID));
                    CallFiled();
                    break;
                case CallStatusType.StartCalling:
                    break;
                case CallStatusType.Hangup:
                    ShowCallState(string.Format(TVString.STR_F_Hangup, TVVS.CallindID));
                    CallFiled();
                    break;
                default:
                    break;
            }
        }

        #endregion


        #region Method

        private void InputCheck()
        {
            btn_VideoCall.Enabled = !string.IsNullOrEmpty(txt_VideoCallInput.Text.Trim()) & txt_VideoCallInput.Text.Trim() != ApplicationData.Account;
        }

        private async void VideoCall()
        {
            if (!btn_VideoCall.Enabled) return;

            if (!SetCaptures())
            {
                Windows_MessageBox wbox = new Windows_MessageBox(TVString.STR_VideooError_Micerr, MessageBoxButtons.OK, MessageBoxIcon.Error);
                wbox.ShowDialog(this);
                return;
            }

            Windows_Main.Instance.MenuActive = false;

            ApplicationData.tmpCallID = txt_VideoCallInput.Text.Trim();
            btn_VideoCall.Enabled = false;
            table_CaptureSetting.Enabled = false;
            cb_ShardScreen.Enabled = false;
            if (calling)
            {
                return;
            }
            calling = true;
            winDisplay = new Windows_Display();
            winDisplay.DspType = cb_Camera.Checked ? DisplayType.TwoScreen : DisplayType.OneScreen;
            int remote = ((Windows_Display)winDisplay).RemoteHandle;
            int local = ((Windows_Display)winDisplay).LocalHandle;
            TVVS.SetScreen(remote, local);
            TVVS.VideoCall(ApplicationData.tmpCallID, CallType.Video);
            ShowCallState(string.Format(TVString.STR_F_Calling, TVVS.CallindID));
            await Task.Delay(1000);
            btn_VideoCall.Visible = false;
            btn_Hangup.Visible = true;
            btn_Hangup.Enabled = true;
        }

        public void Hangup()
        {
            ShowCallState(TVString.STR_NoCalling);
            CallFiled();
        }

        private void UpdateCapturesList()
        {
            var tvCams = TVVS.CameraList();
            var tvMics = TVVS.MicphoneList();
            var tvRsls = ApplicationData.listRsl;
            var tvSpks = TVVS.SpeakerList();

            camSource.DataSource = TVVS.CameraList();
            micSource.DataSource = TVVS.MicphoneList();
            rslSource.DataSource = ApplicationData.listRsl;
            spkSource.DataSource = TVVS.SpeakerList();

            if (camSource.Count == 0)
            {
                cb_Camera.Checked = false;
                cb_Camera.Enabled = false;
                cbox_Camera.Enabled = false;
                cbox_Resolution.Enabled = false;
                ////cb_Camera.Checked = true;
                //cb_Camera.Enabled = true;
                //cbox_Camera.Enabled = true;
                //cbox_Resolution.Enabled = true;
            }

            if (TVVS.MicrophoneErr)
            {
                cbox_Microphone.Enabled = false;
            }
            else
            {
                cbox_Microphone.Enabled = true;
            }

            if (spkSource.Count == 0)
            {
                cbox_Speaker.Enabled = false;
            }
        }

        private void CapturesListChanged()
        {
            camSource.ResetBindings(false);
            micSource.ResetBindings(false);
            rslSource.ResetBindings(false);
            spkSource.ResetBindings(false);
        }

        private bool SetCaptures()
        {
            if (TVVS.MicrophoneErr) return false;
            TVVS.SetMicrophoneProperty(true, true, true);
            int camIndex = ApplicationData.tmpCameraIndex;
            int micIndex = ApplicationData.tmpMicrophoneIndex;
            int spkIndex = ApplicationData.tmpSpeakerIndex;
            string rsl = ApplicationData.tmpResolution;
            rsl = cbox_Resolution.SelectedItem.ToString();
            TVVS.SetCaptures(camIndex, spkIndex, micIndex, rsl);

            return true;
        }

        private void Connected()
        {
            Windows_Main.Instance.ShowVideoDisplay(winDisplay);
            this.Hide();
            Windows_Main.Instance.MenuActive = true;
        }

        private async void CallFiled()
        {
            if (!calling) return;
            btn_Hangup.Enabled = false;
            Windows_Main.Instance.Hangup();
            await Task.Delay(1500);
            btn_Hangup.Visible = false;
            btn_VideoCall.Visible = true;
            btn_VideoCall.Enabled = true;
            calling = false;
            table_CaptureSetting.Enabled = true;
            cb_ShardScreen.Enabled = true;
            Windows_Main.Instance.MenuActive = true;
        }

        private void ShowCallState(string msg)
        {
            icon_VideoCall._Text = msg;
        }

        #endregion

    }
}
